Categories
MongoDB

Using MongoDB with Mongoose — Model Validation

Spread the love

To make MongoDB database manipulation easy, we can use the Mongoose NPM package to make working with MongoDB databases easier.

In this article, we’ll look at how to use Mongoose to manipulate our MongoDB database.

Validation

Mongoose comes with validation features for schemas.

All SchemaTypes have a built-in validator.

Numbers have min and max validators.

And strings have enum, match, minlength, and maxlength validators.

For example, we can write:

async function run() {
  const { createConnection, Schema } = require('mongoose');
  const connection = createConnection('mongodb://localhost:27017/test');
  const breakfastSchema = new Schema({
    eggs: {
      type: Number,
      min: [6, 'too few eggs'],
      max: 12
    },
    bacon: {
      type: Number,
      required: [true, 'too few bacon']
    },
    drink: {
      type: String,
      enum: ['orange juice', 'apple juice'],
      required() {
        return this.bacon > 3;
      }
    }
  });
  const Breakfast = connection.model('Breakfast', breakfastSchema);
  const badBreakfast = new Breakfast({
    eggs: 2,
    bacon: 0,
    drink: 'Milk'
  });
  let error = badBreakfast.validateSync();
  console.log(error);
}
run();

We create the Breakfast schema with some validators.

The eggs field have the min and max validators.

The 2nd entry of the min array has the error message.

We have similar validation with the bacon field.

The drink field has more validation. We have the required method to check other fields to make this field required only if this.bacon is bigger than 3.

enum has the valid values for the drink field.

Therefore, when we create the Breakfast instance with invalid values as we in the code above, we’ll see the errors after we run the validateSync method.

The messages are in the message property in the errors object.

For example, we can write:

async function run() {
  const { createConnection, Schema } = require('mongoose');
  const connection = createConnection('mongodb://localhost:27017/test');
  const breakfastSchema = new Schema({
    eggs: {
      type: Number,
      min: [6, 'too few eggs'],
      max: 12
    },
    bacon: {
      type: Number,
      required: [true, 'too few bacon']
    },
    drink: {
      type: String,
      enum: ['orange juice', 'apple juice'],
      required() {
        return this.bacon > 3;
      }
    }
  });
  const Breakfast = connection.model('Breakfast', breakfastSchema);
  const badBreakfast = new Breakfast({
    eggs: 2,
    bacon: 0,
    drink: 'Milk'
  });
  let error = badBreakfast.validateSync();
  console.log(error.errors['eggs'].message === 'too few eggs');
}
run();

to get the error as we did in the last line of the run function.

The unique option isn’t a validator. It lets us add unique indexes to a field.

For example, we can write:

async function run() {
  const { createConnection, Schema } = require('mongoose');
  const connection = createConnection('mongodb://localhost:27017/test');
  const uniqueUsernameSchema = new Schema({
    username: {
      type: String,
      unique: true
    }
  });
}
run();

to add a unique index to the usernamd field.

We can also add a custom validator. For instance, we can write:

async function run() {
  const { createConnection, Schema } = require('mongoose');
  const connection = createConnection('mongodb://localhost:27017/test');
  const userSchema = new Schema({
    email: {
      type: String,
      validate: {
        validator(v) {
          return /(.+)@(.+){2,}.(.+){2,}/.test(v);
        },
        message: props => `${props.value} is not a email!`
      },
      required: [true, 'Email is required']
    }
  });
  const User = connection.model('User', userSchema);
}
run();

We add the email field to with the validate method with the validator function to add validation for the email field.

The message method is a function that returns the error message if validation fails.

Conclusion

We can add validation in various ways with Mongoose.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *